
package NewGuy;
import ThreeDEntities.RectangularPrism;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.lwjgl.util.vector.*;
import org.lwjgl.LWJGLException;
import org.lwjgl.Sys;
import org.lwjgl.input.Mouse;
import org.lwjgl.input.Keyboard;
import org.lwjgl.opengl.*;
import static org.lwjgl.opengl.GL11.*;
import utility.*;

/**
 * LWJGLApp.java
 * Created on May 6, 2014
 * Author Joe Porter
 */
public class LWJGLApp {

    
    static boolean w,a,s,d;
    static float dX,dY;
    static float mouseSpeed = .5f;
    static float moveSpeed = 10;
    static float maxLookUp = 70, maxLookDown = -70;
    static Vector3f position;
   
    static float delta;
    
    static Camera cam;
    static long lastFrame;
    static long lastFPS;
    static boolean printFPS;
    static int fps;
    static int testmodel;
    static Model m;
    
    static float spin;
    private static int bunnyDisplayList;
    private static String MODEL_LOCATION = "res/monkey3.obj";
    
    static RectangularPrism cube;
    
    
        public static void main(String[] args){
            Mouse.setGrabbed(true);
            initDisplay();
            //setUpDisplayLists();
            gameLoop();
            cleanUp();
        }
        
        public static void gameLoop() {
            
        cam= new Camera(70,(float)Display.getWidth()/(float)Display.getHeight(), 0.3f,1000);
        getDelta();
        lastFPS = getTime();
        cube = new RectangularPrism(0,0,-10,2,2,2);
        
        
        
        while(!Display.isCloseRequested()){
            
            glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
            
            glLoadIdentity();      
            
            cam.useView();
            
            delta = getDelta();
            
            getInput();
            look();
            move();
            //glRotatef(90, 1, 0, 0);
            //System.out.println(cube.getY());
            cube.update(delta);
            collide(cam,cube);
            //glCallList(bunnyDisplayList);
            
            if(spin<360){
                spin++;
            }else{spin=spin-360;}
            Display.update();
            Display.sync(60);
        }
    }

    public static void initDisplay() {
            try {
                Display.setDisplayMode(new DisplayMode(800,600));
                Display.create();
            } catch (LWJGLException ex) {
                Logger.getLogger(LWJGLApp.class.getName()).log(Level.SEVERE, null, ex);
            }
        
    }

    public static void cleanUp() {
        Display.destroy();
    }
    
    public static void getInput(){
        w = Keyboard.isKeyDown(Keyboard.KEY_W);
        a = Keyboard.isKeyDown(Keyboard.KEY_A);
        s = Keyboard.isKeyDown(Keyboard.KEY_S);
        d = Keyboard.isKeyDown(Keyboard.KEY_D);
        
        dX = Mouse.getDX() * mouseSpeed;
        dY = Mouse.getDY() * mouseSpeed;
        
      
    }
    public static void look(){
        //Set Left/Right Look
            if(cam.getRY() + dX >=360){
                cam.setRY(cam.getRY()+dX-360);
            }else if (cam.getRY() + dX <0){
                cam.setRY(360-cam.getRY()+dX);
            }else {
                cam.setRY(cam.getRY() + dX);
            }
            //Set and limit Up/Down Look
            if(cam.getRX() - dY >= maxLookDown && cam.getRX() - dY<=maxLookUp){
                cam.setRX(cam.getRX()- dY);
            }else if(cam.getRX()-dY < maxLookDown){
                cam.setRX(maxLookDown);
            }else if(cam.getRX()-dY > maxLookUp){
                cam.setRX(maxLookUp);
            }
    }
    public static void move(){
        position = new Vector3f(cam.getX(),cam.getY(),cam.getZ());
        //Forward
        if(w && !a && !d && !s){
            float angle = cam.getRY();
            Vector3f newPosition = position;
            float hyp =  (moveSpeed * .0002f) * delta;
            float adj = hyp * (float) Math.cos(Math.toRadians(angle));
            float opp = (float) (Math.sin(Math.toRadians(angle))*hyp);
            newPosition.z += adj;
            newPosition.x -=opp;
            position.z = newPosition.z;
            position.x = newPosition.x;
            
        }
        //A
        if(!w && a && !d && !s){
            float angle = cam.getRY()-90;
            Vector3f newPosition = position;
            float hyp =  (moveSpeed * .0002f) * delta;
            float adj = hyp * (float) Math.cos(Math.toRadians(angle));
            float opp = (float) (Math.sin(Math.toRadians(angle))*hyp);
            newPosition.z += adj;
            newPosition.x -=opp;
            position.z = newPosition.z;
            position.x = newPosition.x;
            
        }
        //D
        if(!w && !a && d && !s){
            float angle = cam.getRY()+90;
            Vector3f newPosition = position;
            float hyp =  (moveSpeed * .0002f) * delta;
            float adj = hyp * (float) Math.cos(Math.toRadians(angle));
            float opp = (float) (Math.sin(Math.toRadians(angle))*hyp);
            newPosition.z += adj;
            newPosition.x -=opp;
            position.z = newPosition.z;
            position.x = newPosition.x;
            
        }
        //W + A
        if(w && a && !d && !s){
            float angle = cam.getRY() -45;
            Vector3f newPosition = position;
            float hyp =  (moveSpeed * .0002f) * delta;
            float adj = hyp * (float) Math.cos(Math.toRadians(angle));
            float opp = (float) (Math.sin(Math.toRadians(angle))*hyp);
            newPosition.z += adj;
            newPosition.x -=opp;
            position.z = newPosition.z;
            position.x = newPosition.x;
            
        }
        //W + D
        if(w && !a && d && !s){
            float angle = cam.getRY() +45;
            Vector3f newPosition = position;
            float hyp =  (moveSpeed * .0002f) * delta;
            float adj = hyp * (float) Math.cos(Math.toRadians(angle));
            float opp = (float) (Math.sin(Math.toRadians(angle))*hyp);
            newPosition.z += adj;
            newPosition.x -=opp;
            position.z = newPosition.z;
            position.x = newPosition.x;
            
        }
        //Backwards
        if(!w && !a && !d && s){
            float angle = cam.getRY();
            Vector3f newPosition = position;
            float hyp =  -(moveSpeed * .0002f) * delta;
            float adj = hyp * (float) Math.cos(Math.toRadians(angle));
            float opp = (float) (Math.sin(Math.toRadians(angle))*hyp);
            newPosition.z += adj;
            newPosition.x -=opp;
            position.z = newPosition.z;
            position.x = newPosition.x;
            
        }
        //S + A
        if(!w && a && !d && s){
            float angle = cam.getRY() +45;
            Vector3f newPosition = position;
            float hyp =  -(moveSpeed * .0002f) * delta;
            float adj = hyp * (float) Math.cos(Math.toRadians(angle));
            float opp = (float) (Math.sin(Math.toRadians(angle))*hyp);
            newPosition.z += adj;
            newPosition.x -=opp;
            position.z = newPosition.z;
            position.x = newPosition.x;
            
        }
        //S + D
        if(!w && !a && d && s){
            float angle = cam.getRY() -45;
            Vector3f newPosition = position;
            float hyp =  -(moveSpeed * .0002f) * delta;
            float adj = hyp * (float) Math.cos(Math.toRadians(angle));
            float opp = (float) (Math.sin(Math.toRadians(angle))*hyp);
            newPosition.z += adj;
            newPosition.x -=opp;
            position.z = newPosition.z;
            position.x = newPosition.x;
            
        }
        cam.setX(position.x);
        cam.setY(position.y);
        cam.setZ(position.z);
    }
    private static long getTime() {
        return (Sys.getTime() * 1000) / Sys.getTimerResolution();
    }
    private static int getDelta() {
        long currentTime = getTime();
        int delta = (int) (currentTime - lastFrame);
        lastFrame = getTime();
        return delta;
    }
    private static void updateFPS() {
        if (getTime() - lastFPS > 1000) {
            if (printFPS) {
                System.out.println("FPS: " + fps);
            }
            fps = 0;
            lastFPS += 1000;
        }
        fps++;
    }
    private static void setUpDisplayLists() {
        bunnyDisplayList = glGenLists(1);
        glNewList(bunnyDisplayList, GL_COMPILE);
        {
            Model m = null;
            try {
                m = OBJLoader.loadModel(new File(MODEL_LOCATION));
            } catch (FileNotFoundException e) {
                e.printStackTrace();
                Display.destroy();
                System.exit(1);
            } catch (IOException e) {
                e.printStackTrace();
                Display.destroy();
                System.exit(1);
            }
            glBegin(GL_TRIANGLES);
            for (Model.Face face : m.getFaces()) {
                Vector3f n1 = m.getNormals().get(face.getNormalIndices()[0] - 1);
                glNormal3f(n1.x, n1.y, n1.z);
                Vector3f v1 = m.getVertices().get(face.getVertexIndices()[0] - 1);
                glVertex3f(v1.x, v1.y, v1.z);
                Vector3f n2 = m.getNormals().get(face.getNormalIndices()[1] - 1);
                glNormal3f(n2.x, n2.y, n2.z);
                Vector3f v2 = m.getVertices().get(face.getVertexIndices()[1] - 1);
                glVertex3f(v2.x, v2.y, v2.z);
                Vector3f n3 = m.getNormals().get(face.getNormalIndices()[2] - 1);
                glNormal3f(n3.x, n3.y, n3.z);
                Vector3f v3 = m.getVertices().get(face.getVertexIndices()[2] - 1);
                glVertex3f(v3.x, v3.y, v3.z);
            }
            glEnd();
        }
        glEndList();
    }
    public static void collide(Camera cam, RectangularPrism box){
        
        
    }
}

